using System.Collections.Generic;
using UnityEngine;
using GameBaseFramework.Pattern;
using System;
using System.Collections;
using GameBaseFramework.Timer;
using GameBaseFramework.Extension;
using GameUnityFramework.Resource;
using UnityEngine.AddressableAssets;
using GameBaseFramework.FrameWorkCommand;
using streaming;
using GameGraphics;
using UnityEngine.EventSystems;

/// <summary>
/// UI命名空间，实现UIView的基类和管理器
/// </summary>
namespace GameUnityFramework.UIView
{
    /// <summary>
    /// UIView当前的状态
    /// </summary>
    public enum UIViewStatus
    {
        /// <summary>
        /// 加载中
        /// </summary>
        Loading,
        /// <summary>
        /// 加载完毕
        /// </summary>
        On_Going,
        /// <summary>
        /// 关闭
        /// </summary>
        Close
    }

    /// <summary>
    /// UIView的设置，没必要在Open时传或者设置的参数都放这里，在子类中自行设置
    /// </summary>
    public class UIViewSetting
    {
        /// <summary>
        /// 该UIView是否用UnityObjectManager进行回收
        /// </summary>
        public bool _isRecycle = false;

        /// <summary>
        /// 该UIView是否需要Update事件
        /// </summary>
        public bool _EnableUpdate = false;

        /// <summary>
        /// 即使被禁用了，也要执行Update事件
        /// </summary>
        public bool _UpdateWhenDisabled = false;

        /// <summary>
        /// UIView在被关闭之后调用的事件
        /// </summary>
        public Action _EndEvent = null;
    }


    /// <summary>
    /// 用于UIView启动协程的Mono
    /// </summary>
    public class UIViewCoroutine : MonoBehaviour
    {

    }

    /// <summary>
    /// UIView基类
    /// 该基类指示着一个UIView的预制体，当要创建UIview的预制体时，首先创建UIViewBase，然后通过UIViewBase的Open向UIViewManager发出指令加载预制体
    /// </summary>
    public class UIViewBase : MonoBehaviour, Icommand, ITimer
    {
        /// <summary>
        /// 持有UIViewManager
        /// 方便子类直接调用
        /// </summary>
        private UIViewManager _viewManager;

        /// <summary>
        /// Canvas
        /// </summary>
        protected Canvas _canvas { get { return _viewManager.Canvas; } }

        /// <summary>
        /// 销毁时调用的事件
        /// </summary>
        public Action _EndEvent { get; set; }


        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="data"></param>
        public void Init(UIViewManager viewManager, object data = null)
        {
            _viewManager = viewManager;
            BindWidgets();
            OnEnter(data);
        }

        /// <summary>
        /// 绑定组件
        /// </summary>
        protected virtual void BindWidgets() { }

        /// <summary>
        /// 关闭当前界面
        /// </summary>
        public void Close()
        {
            try
            {
                _EndEvent?.Invoke();
            }
            catch
            {
                // ignored
            }
            OnClose();
            GameObject.Destroy(gameObject);
        }

        /// <summary>
        /// 销毁清空所有绑定指令
        /// </summary>
        private void OnDestroy()
        {
            this.UnBindAllSelfCommands();
        }

        /// <summary>
        /// 有些界面需要监听关闭，同时gameObject还要存在
        /// </summary>
        protected virtual void OnClose() { }

        /// <summary>
        /// 完成初始化
        /// 子类入口
        /// </summary>
        protected virtual void OnEnter(object data = null) { }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>() where T : UIViewBase
        {
            Open<T>(null);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data) where T : UIViewBase
        {
            _viewManager.Open<T>(data, null, EViewOpenType.Replace, EViewPriority.Level1, string.Empty);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(EViewOpenType openType) where T : UIViewBase
        {
            _viewManager.Open<T>(null, null, openType, EViewPriority.Level1, string.Empty);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, Transform parent) where T : UIViewBase
        {
            _viewManager.Open<T>(data, parent, EViewOpenType.None, EViewPriority.Level0, string.Empty);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, Transform parent, string prefab) where T : UIViewBase
        {
            _viewManager.Open<T>(data, parent, EViewOpenType.None, EViewPriority.Level0, prefab);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, EViewOpenType openType) where T : UIViewBase
        {
            _viewManager.Open<T>(data, null, openType, EViewPriority.Level1, string.Empty);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, EViewOpenType openType, Action endEvent) where T : UIViewBase
        {
            _viewManager.Open<T>(data, null, openType, EViewPriority.Level1, string.Empty, endEvent);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, EViewOpenType openType, EViewPriority priority) where T : UIViewBase
        {
            _viewManager.Open<T>(data, null, openType, priority, string.Empty);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, EViewOpenType openType, EViewPriority priority, Action endEvent) where T : UIViewBase
        {
            _viewManager.Open<T>(data, null, openType, priority, string.Empty, endEvent);
        }

        /// <summary>
        /// Open UIView
        /// </summary>
        public void Open<T>(object data, EViewOpenType openType, EViewPriority priority, Action endEvent, Action enterEvent) where T : UIViewBase
        {
            _viewManager.Open<T>(data, null, openType, priority, string.Empty, endEvent, enterEvent);
        }

        /// <summary>
        /// 添加界面
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="go"></param>
        public T AddView<T>(object data, GameObject go) where T : UIViewBase
        {
            var view = go.GetOrAddComponent<T>();
            view.Init(_viewManager, data);
            return view;
        }

        /// <summary>
        /// 延迟
        /// </summary>
        protected Timer Delay(float duration, System.Action finishAction)
        {
            return this.CreateTimer(duration, finishAction);
        }
    }
}

